package com.intelligent.system.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.intelligent.system.auth.dto.ContactDTO;
import com.intelligent.system.auth.dto.OrganizationQueryDTO;
import com.intelligent.system.auth.entity.Contact;
import com.intelligent.system.auth.entity.Organization;
import com.intelligent.system.auth.mapper.OrganizationMapper;
import com.intelligent.system.auth.service.ContactService;
import com.intelligent.system.auth.service.OrganizationService;
import com.intelligent.system.auth.dto.OrganizationDTO;
import com.intelligent.system.common.exception.CustomException;
import com.intelligent.system.common.response.ResponseCode;
import com.intelligent.system.common.response.ResultDO;
import com.intelligent.system.common.utils.SnowflakeIdUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 组织机构服务实现类
 */
@Slf4j
@Service
public class OrganizationServiceImpl extends ServiceImpl<OrganizationMapper, Organization> implements OrganizationService {

    @Resource
    private OrganizationMapper organizationMapper;

    @Resource
    private ContactService contactService;

    @Resource
    private SnowflakeIdUtils idUtils;

    @Override
    public ResultDO<OrganizationDTO> getOrganizationById(Long id) {
        try {
            log.info("根据ID查询组织机构, id: {}", id);
            Organization organization = organizationMapper.selectById(id);
            if (organization == null) {
                log.warn("组织机构不存在, id: {}", id);
                throw new CustomException("组织机构不存在", ResponseCode.NOT_FOUND.getCode());
            }
            OrganizationDTO dto = new OrganizationDTO();
            BeanUtils.copyProperties(organization, dto);
            return ResultDO.success(dto);
        } catch (CustomException e) {
            throw e;
        } catch (Exception e) {
            log.error("根据ID查询组织机构异常, id: {}", id, e);
            throw new CustomException("查询组织机构失败", ResponseCode.SYSTEM_ERROR.getCode(), e);
        }
    }

    @Override
    public ResultDO<List<OrganizationDTO>> listAll() {
        try {
            log.info("查询所有组织机构");
            List<Organization> organizations = organizationMapper.selectList(
                new LambdaQueryWrapper<Organization>()
                    .eq(Organization::getIsDelete, 0)
                    .orderByAsc(Organization::getOrderNum)
            );
            List<OrganizationDTO> list = organizations.stream()
                    .map(organization -> {
                        OrganizationDTO dto = new OrganizationDTO();
                        BeanUtils.copyProperties(organization, dto);
                        return dto;
                    })
                    .collect(Collectors.toList());
            return ResultDO.success(list);
        } catch (Exception e) {
            log.error("查询所有组织机构异常", e);
            throw new CustomException("查询组织机构列表失败", ResponseCode.SYSTEM_ERROR.getCode(), e);
        }
    }

    @Override
    public ResultDO<List<OrganizationDTO>> listByParentId(Long parentId) {
        try {
            log.info("根据父ID查询组织机构列表, parentId: {}", parentId);
            if (parentId == null) {
                throw new CustomException("父组织机构ID不能为空", ResponseCode.BAD_REQUEST.getCode());
            }
            List<Organization> organizations = organizationMapper.selectByParentId(parentId);
            List<OrganizationDTO> list = organizations.stream()
                    .map(organization -> {
                        OrganizationDTO dto = new OrganizationDTO();
                        BeanUtils.copyProperties(organization, dto);
                        return dto;
                    })
                    .collect(Collectors.toList());
            return ResultDO.success(list);
        } catch (CustomException e) {
            throw e;
        } catch (Exception e) {
            log.error("根据父ID查询组织机构列表异常, parentId: {}", parentId, e);
            throw new CustomException("查询组织机构列表失败", ResponseCode.SYSTEM_ERROR.getCode(), e);
        }
    }

    @Override
    public ResultDO<IPage<OrganizationDTO>> page(OrganizationQueryDTO param) {
        try {
            log.info("分页查询组织机构列表, queryDTO: {}", param);
            Page<Organization> page = new Page<>(param.getPageNum(), param.getPageSize());
            LambdaQueryWrapper<Organization> wrapper = new LambdaQueryWrapper<>();

            // 添加查询条件
            if (StringUtils.hasText(param.getOrgName())) {
                wrapper.like(Organization::getOrgName, param.getOrgName());
            }
            if (StringUtils.hasText(param.getOrgType())) {
                wrapper.eq(Organization::getOrgType, param.getOrgType());
            }
            if (StringUtils.hasText(param.getOrgCode())) {
                wrapper.eq(Organization::getOrgCode, param.getOrgCode());
            }
            if (StringUtils.hasText(param.getParentOrgCode())) {
                wrapper.eq(Organization::getParentOrgCode, param.getParentOrgCode());
            }
            if (param.getOnDuty() != null) {
                wrapper.eq(Organization::getOnDuty, param.getOnDuty());
            }
            if (StringUtils.hasText(param.getJurisdiction())) {
                wrapper.eq(Organization::getJurisdiction, param.getJurisdiction());
            }

            // 添加排序条件
            wrapper.orderByAsc(Organization::getOrderNum);
            wrapper.eq(Organization::getIsDelete, 0);

            IPage<Organization> organizationPage = this.page(page, wrapper);
            Page<OrganizationDTO> dtoPage = new Page<>();
            BeanUtils.copyProperties(organizationPage, dtoPage, "records");
            dtoPage.setRecords(organizationPage.getRecords().stream()
                    .map(organization -> {
                        OrganizationDTO dto = new OrganizationDTO();
                        BeanUtils.copyProperties(organization, dto);
                        return dto;
                    })
                    .collect(Collectors.toList()));
            return ResultDO.success(dtoPage);
        } catch (Exception e) {
            log.error("分页查询组织机构列表异常, param: {}", param, e);
            throw new CustomException("分页查询组织机构列表失败", ResponseCode.SYSTEM_ERROR.getCode(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDO<?> save(OrganizationDTO organizationDTO) {
        try {
            log.info("新增组织机构, organizationDTO: {}", organizationDTO);
            if (organizationDTO == null) {
                throw new CustomException("组织机构信息不能为空", ResponseCode.BAD_REQUEST.getCode());
            }
            Organization organization = new Organization();
            BeanUtils.copyProperties(organizationDTO, organization);
            organization.setOrgId(idUtils.nextId());
            if (this.save(organization)) {
                return ResultDO.success(null);
            }
            throw new CustomException("系统错误", ResponseCode.SYSTEM_ERROR.getCode());
        } catch (CustomException e) {
            throw e;
        } catch (Exception e) {
            log.error("新增组织机构异常, organizationDTO: {}", organizationDTO, e);
            throw new CustomException("新增组织机构失败", ResponseCode.SYSTEM_ERROR.getCode(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDO<?> update(OrganizationDTO organizationDTO) {
        try {
            log.info("更新组织机构, organizationDTO: {}", organizationDTO);
            if (organizationDTO == null || organizationDTO.getOrgId() == null) {
                throw new CustomException("组织机构信息或ID不能为空", ResponseCode.BAD_REQUEST.getCode());
            }
            // 检查组织机构是否存在
            Organization existingOrg = this.getById(organizationDTO.getOrgId());
            if (existingOrg == null) {
                throw new CustomException("组织机构不存在", ResponseCode.NOT_FOUND.getCode());
            }
            Organization organization = new Organization();
            BeanUtils.copyProperties(organizationDTO, organization);
            if (this.updateById(organization)) {
                return ResultDO.success(null);
            }
            throw new CustomException("系统错误", ResponseCode.SYSTEM_ERROR.getCode());
        } catch (CustomException e) {
            throw e;
        } catch (Exception e) {
            log.error("更新组织机构异常, organizationDTO: {}", organizationDTO, e);
            throw new CustomException("更新组织机构失败", ResponseCode.SYSTEM_ERROR.getCode(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDO<?> deleteById(Long id) {
        try {
            log.info("删除组织机构, id: {}", id);
            if (id == null) {
                throw new CustomException("组织机构ID不能为空", ResponseCode.BAD_REQUEST.getCode());
            }
            // 检查组织机构是否存在
            Organization organization = getById(id);
            if (organization == null) {
                throw new CustomException("组织机构不存在", ResponseCode.NOT_FOUND.getCode());
            }
            // 逻辑删除
            organization.setIsDelete(1);

            if (this.updateById(organization)) {
                return ResultDO.success(null);
            }
            throw new CustomException("系统错误", ResponseCode.SYSTEM_ERROR.getCode());
        } catch (CustomException e) {
            throw e;
        } catch (Exception e) {
            log.error("删除组织机构异常, id: {}", id, e);
            throw new CustomException("删除组织机构失败", ResponseCode.SYSTEM_ERROR.getCode(), e);
        }
    }

    @Override
    public ResultDO<OrganizationDTO> getByOrgCode(String orgCode) {
        try {
            log.info("根据组织机构编码查询组织机构, orgCode: {}", orgCode);
            Organization organization = this.getOne(new LambdaQueryWrapper<Organization>()
                    .eq(Organization::getOrgCode, orgCode)
                    .eq(Organization::getIsDelete, 0));
            if (organization == null) {
                throw new CustomException("组织机构不存在", ResponseCode.NOT_FOUND.getCode());
            }
            OrganizationDTO dto = new OrganizationDTO();
            BeanUtils.copyProperties(organization, dto);
            return ResultDO.success(dto);
        } catch (CustomException e) {
            throw e;
        } catch (Exception e) {
            log.error("根据组织机构编码查询组织机构异常, orgCode: {}", orgCode, e);
            throw new CustomException("查询组织机构失败", ResponseCode.SYSTEM_ERROR.getCode(), e);
        }
    }

    @Override
    public ResultDO<OrganizationDTO> getOrganizationWithContacts(Long id) {
        try {
            log.info("获取组织机构及其联系人信息, id: {}", id);
            Organization organization = getById(id);
            if (organization == null) {
                throw new CustomException("组织机构不存在", ResponseCode.NOT_FOUND.getCode());
            }
            ResultDO<List<ContactDTO>> res = contactService.listByOrganizationId(id);
            OrganizationDTO dto = new OrganizationDTO();
            BeanUtils.copyProperties(organization, dto);
            dto.setContacts(res.getData());
            return ResultDO.success(dto);
        } catch (CustomException e) {
            throw e;
        } catch (Exception e) {
            log.error("获取组织机构及其联系人信息异常, id: {}", id, e);
            throw new CustomException("获取组织机构及其联系人信息失败", ResponseCode.SYSTEM_ERROR.getCode(), e);
        }
    }

} 